package memleak.test.com.testlist;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.Nullable;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;


import com.gzgd.log.LogUtils;

import java.util.List;

/**
 * Created by runrun on 2017/2/16.
 */

public class ChannelRecyclerView extends RecyclerView implements IA {

    public static final int RANGE = 7;
    private static final String TAG = "ChannelRecyclerView";
    private static final int JUMP_RANGE = 5;
    private ChannelRecyclerViewAdapter mAdapter;
    private CycleLayoutManager mCycleLayoutManager;
    private LiveApplication mApp;
    private boolean isMove;
    private int mPos;

    public ChannelRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {

        super(context, attrs, defStyle);
        LogUtils.d("xxx", "Pos:  1 " );
        setFocusable(false);
        mCycleLayoutManager = new CycleLayoutManager(context);
        mCycleLayoutManager.setOrientation(VERTICAL);
        setLayoutManager(mCycleLayoutManager);
        setItemAnimator(new DefaultItemAnimator());
        addItemDecoration(new DividerItemDecoration(context, VERTICAL));
        LogUtils.d("xxx", "Pos:  2  " );
        addOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                    if (isMove) {
//                        isMove = false;

                        locatePos();
                    }
                }
            }

            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (isMove) {

                    locatePos();
                }
            }
        });
        LogUtils.d("xxx", "Pos:  3  " );
        mAdapter = new ChannelRecyclerViewAdapter();
        setAdapter(mAdapter);
        mApp = (LiveApplication) ((Activity) context).getApplication();
        LogUtils.d("xxx", "Pos:  4  " );
    }

    public ChannelRecyclerView(Context context) {
        this(context, null);
    }

    public ChannelRecyclerView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    @Override
    protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {

        int index;
        int increment;
        int end;
        int count = getChildCount();
        if ((direction & FOCUS_FORWARD) != 0) {
            index = 0;
            increment = 1;
            end = count;
        } else {
            index = count - 1;
            increment = -1;
            end = -1;
        }


        Integer x = (Integer) ((View) getParent()).getTag();

        if (mApp.getPagePos() == x) {
            mPos = mApp.getChannelPos();
        }
        LogUtils.d(TAG, "Pos:" + mPos + " tag:" + x + " gPos:" + mApp.getPagePos() + " x:" + x + " gChannelPos:" + mApp.getChannelPos());

        if (mPos != 0) {
            for (int i = index; i != end; i += increment) {
                ChannelView child = (ChannelView) getChildAt(i);

                if (child != null && child.getPosition() == mPos) {
                    if (child.requestFocus()) {
                        return true;
                    }
                }

            }
            setCurrentItem(mPos);
        } else {
            for (int i = index; i != end; i += increment) {
                View child = getChildAt(i);
                if (child.getVisibility() == VISIBLE) {
                    if (child.requestFocus(direction, previouslyFocusedRect)) {
                        return true;
                    }
                }

            }
        }
        return false;
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        setWillNotDraw(false);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (!isAttachedToWindow() || View.VISIBLE != getVisibility()) {
            return;
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }


    @Override
    public void draw(Canvas c) {

        if (!isAttachedToWindow() || View.VISIBLE != getVisibility()) {
            return;
        }
        super.draw(c);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        if ((!isMove && !changed) || !isAttachedToWindow() || View.VISIBLE != getVisibility()) {
            return;
        }
        super.onLayout(changed, l, t, r, b);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    @Override
    public void setup() {

    }


    /**
     * 數字鍵切臺
     *
     * @param logicNum
     */
    public void selectChannelByNumber(int logicNum) {
        mApp.adjustPlay(TransformBeanTool.transforVideoBean(mAdapter.getChannelBeanByLogicNum(logicNum)));
    }


    public void updateDatas(List<LiveChannel> list) {
        if (null == list || list.isEmpty()) {
            return;
        }
        mAdapter.setDatas(list);
    }

    public void updateSingleData(LiveChannel channel) {
        mAdapter.setSingleData(channel);
    }


    @Override
    public void destroy() {

    }

    private void locatePos() {
        int n;
        int first = mCycleLayoutManager.findFirstVisibleItemPosition();
        int last = mCycleLayoutManager.findLastVisibleItemPosition();
        LogUtils.d(TAG, "locatePos first:" + first + " last:" + last + " cur:" + mPos);
        if (first > last) {
            if (mPos >= first) {
                n = mPos - first;
            } else {
                n = mCycleLayoutManager.getItemCount() - first + mPos;
            }

        } else {
            n = mPos - mCycleLayoutManager.findFirstVisibleItemPosition();
        }

        LogUtils.d(TAG, "locatePos n:" + n + " mPos:" + mPos);
        View view = mCycleLayoutManager.getChildAt(n);
        if (view != null) {
            view.requestFocus();
            LogUtils.d(TAG, n + " view request");
            isMove = false;
        } else {
            LogUtils.e(TAG, "locate view is null");
            mCycleLayoutManager.scrollToPosition(mPos);
        }
    }

    public void setCurrentItem(int channelPos) {
        mPos = channelPos;
        LogUtils.d(TAG, "setCurrentItem channelPos:" + channelPos + " size:" + mCycleLayoutManager.getItemCount());

        post(new Runnable() {
            @Override
            public void run() {
                moveToPosition(mPos);
            }
        });
    }

    public LiveChannel getItem(int index) {
        return mAdapter.getItem(index);
    }

    public int getSize() {
        return mAdapter.getItemCount();
    }

    private void moveToPosition(int n) {
        int firstItem = mCycleLayoutManager.findFirstVisibleItemPosition();
        int lastItem = mCycleLayoutManager.findLastVisibleItemPosition();
        LogUtils.d(TAG, "moveToPosition first:" + firstItem + " last:" + lastItem + " n:" + n);
        if (firstItem > lastItem) {
            moveToPositionCycle(n, firstItem, lastItem);
        } else {
            moveToPositionNormal(n, firstItem, lastItem);
        }

    }


    private void moveToPositionCycle(int n, int firstItem, int lastItem) {

        if (n >= firstItem || n <= lastItem) {
            int pos;
            if (n >= firstItem) {
                pos = mPos - firstItem;
            } else {
                pos = mCycleLayoutManager.getItemCount() - firstItem + mPos;
            }

            LogUtils.d(TAG, "target view pos is :" + pos);
            View view = mCycleLayoutManager.getChildAt(pos);
            if (view != null) {
                view.requestFocus();
            }
        } else {
            int prePos = mAdapter.getCurrentPosition();
            LogUtils.d(TAG, "prePos:" + prePos);
            if (n > prePos) {
                n += JUMP_RANGE;
            } else if (n < prePos) {
                n -= JUMP_RANGE;
            }

            int count = mCycleLayoutManager.getItemCount();

            if (n >= count) {
                n = count;
            } else if (n < 0) {
                n = 0;
            }
            isMove = true;
            LogUtils.d(TAG, "moveToPositionCycle n:" + n);
            mCycleLayoutManager.scrollToPosition(n);
        }

    }

    private void moveToPositionNormal(int n, int firstItem, int lastItem) {
        if (n >= firstItem && n <= lastItem) {
            int range = n - firstItem;
            View view = mCycleLayoutManager.getChildAt(range);
            if (view != null) {
                view.requestFocus();
            }
        } else {
            if (firstItem > n) {
                n -= JUMP_RANGE;
            } else {
                n += JUMP_RANGE;
            }
            if (n < 0) {
                n = 0;
            }
            if (n >= mCycleLayoutManager.getItemCount()) {
                n = mCycleLayoutManager.getItemCount() - 1;
            }
            isMove = true;
            mCycleLayoutManager.scrollToPosition(n);

        }
    }

    public LiveChannel getChannelByNumber(int logicNum) {
        return mAdapter.getChannelBeanByLogicNum(logicNum);
    }


    class DividerItemDecoration extends ChannelRecyclerView.ItemDecoration {

        public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
        public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
        private final int[] ATTRS = new int[]{
                android.R.attr.listDivider
        };
        private Drawable mDivider;

        private int mOrientation;

        public DividerItemDecoration(Context context, int orientation) {
            final TypedArray a = context.obtainStyledAttributes(ATTRS);
            mDivider = a.getDrawable(0);
            a.recycle();
            setOrientation(orientation);
        }

        public void setOrientation(int orientation) {
            if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
                throw new IllegalArgumentException("invalid orientation");
            }
            mOrientation = orientation;
        }

        @Override
        public void onDraw(Canvas c, RecyclerView parent) {
            if (mOrientation == VERTICAL_LIST) {
                drawVertical(c, parent);
            } else {
                drawHorizontal(c, parent);
            }

        }

        public void drawVertical(Canvas c, RecyclerView parent) {
            final int left = parent.getPaddingLeft();
            final int right = parent.getWidth() - parent.getPaddingRight();

            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                final ChannelRecyclerView.LayoutParams params = (ChannelRecyclerView.LayoutParams) child
                        .getLayoutParams();
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }

        public void drawHorizontal(Canvas c, RecyclerView parent) {
            final int top = parent.getPaddingTop();
            final int bottom = parent.getHeight() - parent.getPaddingBottom();

            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                final ChannelRecyclerView.LayoutParams params = (ChannelRecyclerView.LayoutParams) child
                        .getLayoutParams();
                final int left = child.getRight() + params.rightMargin;
                final int right = left + mDivider.getIntrinsicHeight();
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }

        @Override
        public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
            if (mOrientation == VERTICAL_LIST) {
                outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
            } else {
                outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
            }
        }
    }

    /**
     * DVB数据结构
     * Created by runrun on 2017/6/14.
     */

    public static class DvbBean implements Cloneable {
        //原始网络ID
        private int originalNetworkId;
        //传输流ID
        private int transportStreamId;
        //服务ID
        private int serviceId;
        //网络ID
        private int networkId;

        @Override
        public DvbBean clone() {
            DvbBean o = null;
            try {
                o = (DvbBean) super.clone();
            } catch (CloneNotSupportedException e) {
                LogUtils.e("DvbBean", "clone error", e);
            }
            return o;
        }


        public int getOriginalNetworkId() {
            return originalNetworkId;
        }

        public void setOriginalNetworkId(int originalNetworkId) {
            this.originalNetworkId = originalNetworkId;
        }

        public int getTransportStreamId() {
            return transportStreamId;
        }

        public void setTransportStreamId(int transportStreamId) {
            this.transportStreamId = transportStreamId;
        }

        public int getServiceId() {
            return serviceId;
        }

        public void setServiceId(int serviceId) {
            this.serviceId = serviceId;
        }

        public int getNetworkId() {
            return networkId;
        }

        public void setNetworkId(int networkId) {
            this.networkId = networkId;
        }
    }
}
